// RTF转HTML
RTFJS.loggingEnabled(false);
WMFJS.loggingEnabled(false);
EMFJS.loggingEnabled(false);

/**
 * 1、封装rtf转换类
 * 参数：对象形式
 * 参数项：data 需要转换的rtf数组
 * 参数项：onSuccess 转换成功
 */
class RtfConverter {
  constructor(params = { data: [], onSuccess: null }) {
    // 1、初始化数据
    Object.assign(this, params);
    // 2、开始转换
    this.startConvert();
  }
  startConvert() {
    if (this.data.length > 0) {
      const _this = this, rtfToHtmlPromises = [];
      // 1、所有rtf转html
      this.data.forEach(function (rtfStr) {
        rtfToHtmlPromises.push(_this.rtfPromise(rtfStr));
      });
      // 2、转换成功后
      Promise.all(rtfToHtmlPromises).then(async (data) => {
        if (data.length == 0) return;
        // 2.1、将所有元素放到 同一个div 元素下，方便操作
        const elemArr = data[0],
          parentWrap = document.createElement("div");
        elemArr.forEach((elem) => parentWrap.appendChild(elem));

        // ------ 追加到文档(否则svg不能转为img)；同时设置定位，减少渲染 ---------
        parentWrap.setAttribute("id", "rtfParentWrap");
        parentWrap.style.position = "absolute";
        document.body.appendChild(parentWrap);

        // 2.2、所有svg标签转为img -- (公式图片特殊处理)
        await svgToImg(parentWrap);
        // 2.3、所有img标签转为file
        const imgArr = parentWrap.querySelectorAll("img"),
          imgConvertFileArr = []; // img file对象
        imgArr.forEach((img, index) => {
          imgConvertFileArr.push(imgToFile(img, index));
        });
        Promise.all(imgConvertFileArr).then((fileArr) => {
          // ------ 调用回调，传回参数 ---------
          _this.onSuccess({ element: parentWrap, file: fileArr });
          document.querySelector("#rtfParentWrap").remove();
        });
      });
    } else {
      // ------ 调用回调 ---------
      this.onSuccess(null);
    }
  }
  rtfPromise(rtfStr) { // rtf转html
    // 将rtf转为html 异步方法
    return new Promise((resolve, reject) => {
      rtfToHtml(rtfStr, (elem) => {
        // rtf转html
        elem ? resolve(elem) : reject();
      });
    });
  }
}

/**
 * 2、rtf.js库 工具类
 * rtfToHtml(): rtf串转html标签
 * stringToArrayBuffer(): 创建二进制数据的原始缓存区
 * */ 
function rtfToHtml(rtf, cb) {
  // 将rtf转为html
  const setting = {
    // 自定义配置
    onPicture: (isLegacy, create) => {
      // 图片只生成img，不生成svg格式
      if (!isLegacy) {
        const elem = create();
        // 需要转换
        if (elem.nodeName == "svg") {
          // svg - 添加父元素
          const parent = document.createElement("span");
          parent.className = "svg-parent";
          parent.style.display = "inline-block";
          parent.appendChild(elem);
          return parent;
        }
        return elem;
      }
    },
  };
  const doc = new RTFJS.Document(stringToArrayBuffer(rtf), setting);
  // const meta = doc.metadata();
  doc
    .render()
    .then(function (htmlElements) {
      // console.log("Meta:");
      // console.log(meta);
      cb(htmlElements);
    })
    .catch((error) => console.error(error));
}
function stringToArrayBuffer(string) {
  // 创建二进制数据的原始缓存区
  const buffer = new ArrayBuffer(string.length);
  const bufferView = new Uint8Array(buffer);
  for (let i = 0; i < string.length; i++) {
    bufferView[i] = string.charCodeAt(i);
  }
  return buffer;
}

/**
 * 3、自定义工具类
 * getUUID(): 获取唯一值
 * svgToImg()：svg标签转img标签
 * imgToFile(): img转file
 * readFileInfo(): 读取file信息
 */
function getUUID() {
  // 获取唯一值
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
    let r = (Math.random() * 16) | 0,
      v = c == "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}
function svgToImg(parentWrap) {
  return new Promise((resolve, reject) => {
    // 公式svg 转 图片
    const svgList = parentWrap.querySelectorAll(".svg-parent");
    if (svgList.length == 0) {
      // 无svg元素
      resolve();
    }
    let finishNum = 0; // 记录svg是否全部转换完成
    svgList.forEach((elem) => {
      const parentNode = elem.parentNode,
        image = document.createElement("img");
      domtoimage
        .toPng(elem)
        .then((base64) => {
          // 将svg替换为图片
          image.src = base64;
          parentNode.replaceChild(image, elem);
          // 判断是否转换完成
          finishNum++;
          finishNum == svgList.length && resolve();
        })
        .catch((error) => {
          // 判断是否转换完成
          finishNum;
          finishNum == svgList.length && reject();
        });
    });
  });
}
function imgToFile(img, index) { // 将图片转换为file文件
  return new Promise((resolve) => {
    const imgId = getUUID(),
      src = img.getAttribute("src");
    // 1、追加ID
    img.setAttribute("id", imgId);
    // 2、将图片转为file文件
    let bytes = window.atob(src.split(",")[1]), //去掉url的头，并转换为byte
      mime = src.split(",")[0].match(/:(.*?);/)[1],
      //处理异常,将ascii码小于0的转换为大于0
      ab = new ArrayBuffer(bytes.length),
      ia = new Uint8Array(ab),
      len = bytes.length,
      fileName = `name-${index}`;
    for (let i = 0; i < len; i++) {
      ia[i] = bytes.charCodeAt(i);
    }
    const file = new File([ab], fileName, { type: mime });
    // 3、获取文件md5, 防止后台重复上传；并更改file的name属性为：md5值-type
    readFileInfo(file).then((asyncFile) => {
      const md5 = SparkMD5.ArrayBuffer.hash(asyncFile),
        type = mime.split('/')[1],
        newFileName = `${md5}.${type}`;
      // 修改file文件名
      const newFile = new File([file], newFileName, { type: mime });
      resolve({[imgId]: newFile});
    });
  });
}
function readFileInfo(file) {
  // 获取文件信息
  const reader = new FileReader();
  return new Promise((resolve, reject) => {
    reader.onerror = (error) => {
      reader.abort();
      reject(error);
    };
    reader.onloadend = () => {
      resolve(reader.result);
    };
    reader.readAsArrayBuffer(file);
  });
}